package gridy.geneticoperations;

import java.util.Random;

import gridy.algorithm.Individual;

public class PolynomialMutation implements Mutation {
    
    private double probability;
    private double eta;
    private Random r;

    public PolynomialMutation() {
        r = new Random();
    }
    
    @Override
    public void mutate(Individual ind) {

        for (int i = 0; i < ind.getGenesNum(); i++) {
            double m = r.nextDouble();
            if (m <= probability) {
                double rnd, deltaq;
                rnd = r.nextDouble();
                if (rnd < 0.5) {
                    deltaq = Math.pow((2 * rnd), (1.0 / (eta + 1.0))) - 1.0;
                } else {
                    deltaq = 1.0 - Math.pow(2 * (1.0 - rnd), 1.0 / (eta + 1.0));
                }
                
                ind.setGene(i, ind.getGene(i) + deltaq * (ind.getBoundry(1) - ind.getBoundry(0)));
            }
        }
        ind.normalizeGenes();
    }

    public void setProbability(double probability) {
        this.probability = probability;
    }

    public void setEta(double eta) {
        this.eta = eta;
    }

    public PolynomialMutation(Double eta, Double probability) {
        this();
        setEta(eta);
        setProbability(probability);
    } 
}
